#include "jzj249350520mainwindow.h"
#include "qmediametadata.h"
#include "ui_jzj249350520mainwindow.h"

#include <QFileDialog>
#include <QMessageBox>
#include <QStatusBar>
#include <QDir>
#include <QCloseEvent>
#include <QTransform>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QUrl>
#include <QVideoSink>
#include <QVideoFrame>
#include <QVideoFrameFormat>
#include <QAction>
#include <opencv2/opencv.hpp>
#include <QTemporaryFile>  // 用于 QTemporaryFile
#include <QJsonDocument>   // 用于 QJsonDocument
#include <QJsonObject>     // 用于 QJsonObject
#include <QJsonArray>      // 用于 QJsonArray
#include <QPainter>
#include <QPen>

JZJ249350520MainWindow::JZJ249350520MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::JZJ249350520MainWindow), pythonProcess(nullptr),
    mediaPlayer(nullptr),
    videoWidget(nullptr),
    videoSlider(nullptr),
    frameTimer(nullptr),
    playPauseButton(nullptr),
    processMethodCombo(nullptr),
    speedCombo(nullptr),
    lastProcessedFrame(),
    brightness(0),
    contrast(1.0)
{
    ui->setupUi(this);
    this->addDockWidget(Qt::RightDockWidgetArea, ui->dockWidget);

    // 初始化视频处理组件
    setupVideoUI();

    setWindowTitle("数字图像处理软件V1.0 金智杰249350520");

    // 信号连接
    connect(ui->actionOpen, &QAction::triggered, this, &JZJ249350520MainWindow::openImage);
    connect(ui->actionSave, &QAction::triggered, this, &JZJ249350520MainWindow::saveImage);
    connect(ui->actionGray, &QAction::triggered, this, &JZJ249350520MainWindow::toGray);
    connect(ui->actionBinary, &QAction::triggered, this, &JZJ249350520MainWindow::toBinary);
    connect(ui->actionMeanFilter, &QAction::triggered, this, &JZJ249350520MainWindow::meanFilter);
    connect(ui->actionGamma, &QAction::triggered, this, &JZJ249350520MainWindow::gammaTransform);
    connect(ui->actionEdgeDetect, &QAction::triggered, this, &JZJ249350520MainWindow::edgeDetect);
    connect(ui->actionAbout, &QAction::triggered, this, &JZJ249350520MainWindow::showAbout);
    connect(ui->actionOpenVideo, &QAction::triggered, this, &JZJ249350520MainWindow::openVideo);
    connect(ui->actionExit, &QAction::triggered, this, &QWidget::close);

    // 阈值滑动条
    connect(sliderThreshold(), &QSlider::valueChanged, this, &JZJ249350520MainWindow::onSliderThresholdChanged);

    // 按钮连接
    connect(ui->btnFlip, &QPushButton::clicked, this, &JZJ249350520MainWindow::on_btnFlip_clicked);
    connect(ui->btnReset, &QPushButton::clicked, this, &JZJ249350520MainWindow::on_btnReset_clicked);
    connect(ui->btnRotateLeft, &QPushButton::clicked, this, &JZJ249350520MainWindow::on_btnRotateLeft_clicked);
    connect(ui->btnRotateRight, &QPushButton::clicked, this, &JZJ249350520MainWindow::on_btnRotateRight_clicked);
    connect(ui->sliderBrightness, &QSlider::valueChanged, this, &JZJ249350520MainWindow::on_sliderBrightness_valueChanged);
    connect(ui->sliderContrast, &QSlider::valueChanged, this, &JZJ249350520MainWindow::on_sliderContrast_valueChanged);

    ui->dockWidget->setVisible(true);
    statusBar()->showMessage("欢迎使用数字图像处理软件！");
}

JZJ249350520MainWindow::~JZJ249350520MainWindow()
{
    delete ui;
    if (mediaPlayer) delete mediaPlayer;
    if (frameTimer) delete frameTimer;
    if (pythonProcess) {
        pythonProcess->kill();
        delete pythonProcess;
    }
    delete ui;
}

void JZJ249350520MainWindow::setupVideoUI()
{
    // 创建视频播放器组件
    mediaPlayer = new QMediaPlayer(this);
    audioOutput = new QAudioOutput(this);
    mediaPlayer->setAudioOutput(audioOutput);

    // 使用 UI 文件中的 videoWidget
    videoWidget = ui->videoWidget;
    mediaPlayer->setVideoOutput(videoWidget);

    // 使用 UI 文件中的控件
    playPauseButton = ui->playPauseButton;
    videoSlider = ui->videoSlider;
    processMethodCombo = ui->processMethodCombo;
    speedCombo = ui->speedCombo;

    // 设置 processMethodCombo 的数据
    processMethodCombo->setItemData(0, 0); // 无处理
    processMethodCombo->setItemData(1, 1); // 灰度化
    processMethodCombo->setItemData(2, 2); // 二值化
    processMethodCombo->setItemData(3, 3); // 边缘检测
    processMethodCombo->setItemData(4, 4); // 3x3均值滤波
    processMethodCombo->setItemData(5, 5); // 局部马赛克

    // 设置 speedCombo 的数据
    speedCombo->setItemData(0, 0.5); // 0.5x
    speedCombo->setItemData(1, 1.0); // 1.0x
    speedCombo->setItemData(2, 1.5); // 1.5x
    speedCombo->setItemData(3, 2.0); // 2.0x
    speedCombo->setCurrentIndex(1); // 默认 1.0x

    // 连接信号槽
    connect(playPauseButton, &QPushButton::clicked, this, &JZJ249350520MainWindow::toggleVideoPlayback);
    connect(videoSlider, &QSlider::sliderMoved, this, &JZJ249350520MainWindow::onVideoSliderMoved);
    connect(mediaPlayer, &QMediaPlayer::positionChanged, this, &JZJ249350520MainWindow::updateVideoSlider);
    connect(mediaPlayer, &QMediaPlayer::durationChanged, videoSlider, &QSlider::setMaximum);
    connect(speedCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &JZJ249350520MainWindow::on_speedCombo_currentIndexChanged);
    connect(ui->actionDetectFlames, &QAction::triggered, this, &JZJ249350520MainWindow::detectFlames);
    // 连接 QProcess 信号
    connect(pythonProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
            this, &JZJ249350520MainWindow::onFlameDetectionFinished);
    // 使用定时器处理视频帧
    frameTimer = new QTimer(this);
    connect(frameTimer, &QTimer::timeout, this, &JZJ249350520MainWindow::processCurrentFrame);
    frameTimer->start(33); // 约 30fps
}

void JZJ249350520MainWindow::processCurrentFrame()
{
    if (!mediaPlayer || mediaPlayer->playbackState() != QMediaPlayer::PlayingState)
        return;

    int operation = processMethodCombo->currentData().toInt();
    if (operation == 0)  // 无处理
        return;

    QVideoSink* sink = mediaPlayer->videoSink();
    if (!sink) {
        qWarning() << "无法获取 QVideoSink";
        return;
    }

    QVideoFrame frame = sink->videoFrame();
    if (!frame.isValid()) {
        qWarning() << "无效的视频帧";
        return;
    }

    // 1) 转成 QImage，强制成 BGRA 内存布局
    QImage image = frame.toImage().convertToFormat(QImage::Format_ARGB32);
    if (image.isNull()) {
        qWarning() << "无法将视频帧转换为 QImage";
        return;
    }

    try {
        // 2) 用 QImage buffer 构造 OpenCV Mat (CV_8UC4, BGRA)
        cv::Mat cvFrame(
            image.height(),
            image.width(),
            CV_8UC4,
            const_cast<uchar*>(image.constBits()),
            image.bytesPerLine()
            );

        cv::Mat gray, processedFrame;
        switch (operation) {
        case 1: // 灰度化
            cv::cvtColor(cvFrame, gray, cv::COLOR_BGRA2GRAY);
            cv::cvtColor(gray, processedFrame, cv::COLOR_GRAY2BGRA);
            break;
        case 2: // 二值化
            cv::cvtColor(cvFrame, gray, cv::COLOR_BGRA2GRAY);
            cv::threshold(gray, gray, 128, 255, cv::THRESH_BINARY);
            cv::cvtColor(gray, processedFrame, cv::COLOR_GRAY2BGRA);
            break;
        case 3: // 边缘检测
            cv::cvtColor(cvFrame, gray, cv::COLOR_BGRA2GRAY);
            cv::Canny(gray, gray, 100, 200);
            cv::cvtColor(gray, processedFrame, cv::COLOR_GRAY2BGRA);
            break;
        case 4: // 3x3 均值滤波
            cv::blur(cvFrame, processedFrame, cv::Size(3, 3));
            break;
        case 5: // 局部马赛克
            processedFrame = applyMosaic(cvFrame);
            break;
        default:
            processedFrame = cvFrame.clone();
        }

        if (processedFrame.empty()) {
            qWarning() << "处理后的帧为空";
            return;
        }

        // 3) Mat → QImage，继续用 Format_ARGB32(BGRA)
        QImage result(
            processedFrame.data,
            processedFrame.cols,
            processedFrame.rows,
            processedFrame.step,
            QImage::Format_ARGB32
            );

        // 4) 构造输出格式：BGRA8888 对应 QImage::Format_ARGB32
        QVideoFrameFormat fmt(
            result.size(),
            QVideoFrameFormat::PixelFormat::Format_BGRA8888
            );
        QVideoFrame outFrame(fmt);

        // 5) map + memcpy
        if (!outFrame.map(QVideoFrame::WriteOnly)) {
            qWarning() << "无法映射输出 QVideoFrame";
            return;
        }
        memcpy(outFrame.bits(0),
               result.constBits(),
               result.sizeInBytes());
        outFrame.unmap();

        // 6) 提交到视频接收器
        sink->setVideoFrame(outFrame);
        lastProcessedFrame = result;  // 如果需要回看

    } catch (const cv::Exception& e) {
        qWarning() << "OpenCV 异常:" << e.what();
    }
}




cv::Mat JZJ249350520MainWindow::applyMosaic(cv::Mat input, int blockSize)
{
    cv::Mat output = input.clone();
    int centerX = output.cols / 2;
    int centerY = output.rows / 2;
    int width = output.cols / 3;
    int height = output.rows / 3;

    cv::Rect roi(centerX - width/2, centerY - height/2, width, height);
    cv::Mat region = output(roi);

    cv::Mat temp;
    cv::resize(region, temp, cv::Size(width/blockSize, height/blockSize), 0, 0, cv::INTER_NEAREST);
    cv::resize(temp, region, cv::Size(width, height), 0, 0, cv::INTER_NEAREST);

    return output;
}

void JZJ249350520MainWindow::toggleVideoPlayback()
{
    if (!mediaPlayer) return;

    if (mediaPlayer->playbackState() == QMediaPlayer::PlayingState) {
        mediaPlayer->pause();
        playPauseButton->setText("播放");
        lastProcessedFrame = QImage(); // 清空保存的帧
    } else {
        mediaPlayer->play();
        playPauseButton->setText("暂停");
        lastProcessedFrame = QImage(); // 清空保存的帧
    }
}

void JZJ249350520MainWindow::updateVideoSlider(qint64 position)
{
    if (videoSlider) {
        videoSlider->setValue(position);
    }
}

void JZJ249350520MainWindow::onVideoSliderMoved(int position)
{
    if (mediaPlayer) {
        mediaPlayer->setPosition(position);
    }
}

void JZJ249350520MainWindow::on_speedCombo_currentIndexChanged(int index)
{
    if (!mediaPlayer) return;
    double speed = speedCombo->itemData(index).toDouble();
    mediaPlayer->setPlaybackRate(speed);
    statusBar()->showMessage(QString("播放速度设置为: %1x").arg(speed));
}
void JZJ249350520MainWindow::detectFlames()
{
    if (!isImageLoaded()) {
        showMsgBox("提示", "请先打开图片！");
        return;
    }

    try {
        // 保存当前图片为临时文件
        QTemporaryFile tempFile(QDir::tempPath() + "/detect_XXXXXX.jpg");
        tempFile.setAutoRemove(false);  // 关键：防止被自动删除
        if (!tempFile.open()) {
            showMsgBox("错误", "无法创建临时文件！");
            return;
        }
        QString tempFilePath = tempFile.fileName();
        imageCurrent.save(tempFilePath, "JPG");
        tempFile.close();

        // 初始化 QProcess（如果未初始化）
        if (!pythonProcess) {
            pythonProcess = new QProcess(this);
            connect(pythonProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
                    this, &JZJ249350520MainWindow::onFlameDetectionFinished);
        }

        // 启动 Python 脚本
        QString pythonPath = "python";  // 或指定完整路径如 "C:/Python39/python.exe"
        QString scriptPath = "G:/ultralytics/local_yolo_api.py";

        QStringList arguments;
        arguments << scriptPath << tempFile.fileName();

        pythonProcess->start(pythonPath, arguments);
        if (!pythonProcess->waitForStarted(3000)) {
            showMsgBox("错误", "启动 Python 脚本超时！");
            return;
        }

        statusBar()->showMessage("正在检测火焰...");
    } catch (const std::exception &e) {
        showMsgBox("错误", QString("处理失败: %1").arg(e.what()));
    }
}
void JZJ249350520MainWindow::onFlameDetectionFinished()
{
    QByteArray output = pythonProcess->readAllStandardOutput();
    QByteArray error = pythonProcess->readAllStandardError();

    qDebug() << "Python stdout:" << output;
    qDebug() << "Python stderr:" << error;

    if (!error.isEmpty()) {
        showMsgBox("Python 错误", QString::fromLocal8Bit(error));
        return;
    }

    // 提取最后一行 JSON
    QList<QByteArray> lines = output.split('\n');
    QByteArray lastLine;
    for (int i = lines.size() - 1; i >= 0; --i) {
        if (!lines[i].trimmed().isEmpty()) {
            lastLine = lines[i].trimmed();
            break;
        }
    }

    // 解析 JSON
    QJsonParseError parseError;
    QJsonDocument doc = QJsonDocument::fromJson(lastLine, &parseError);
    if (parseError.error != QJsonParseError::NoError) {
        showMsgBox("JSON 解析错误", parseError.errorString());
        return;
    }

    QJsonObject result = doc.object();
    if (result.contains("error")) {
        showMsgBox("检测错误", result["error"].toString());
        return;
    }

    // 将 QImage 转为 OpenCV 处理（不动原图）
    QImage img = imageCurrent.convertToFormat(QImage::Format_RGB888);
    cv::Mat frame(img.height(), img.width(), CV_8UC3, img.bits(), img.bytesPerLine());

    QJsonArray detections = result["detections"].toArray();
    for (const QJsonValue &detection : detections) {
        QJsonObject det = detection.toObject();
        QJsonArray box = det["box"].toArray();

        int x1 = box[0].toInt();
        int y1 = box[1].toInt();
        int x2 = box[2].toInt();
        int y2 = box[3].toInt();
        float conf = det["confidence"].toDouble();

        // 绘制检测框和标签
        cv::rectangle(frame, cv::Point(x1, y1), cv::Point(x2, y2), cv::Scalar(255, 0, 0), 2); // 蓝框
        cv::putText(frame,
                    QString("Fire %1").arg(conf, 0, 'f', 2).toStdString(),
                    cv::Point(x1, y1 - 10),
                    cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(255, 0, 0), 2);
    }

    // 转换为 QImage 并更新 imageCurrent 和 imageOriginal
    imageCurrent = QImage(frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGB888).copy();
    imageOriginal = imageCurrent;

    // 显示（由 showImage 添加中文水印）
    showImage(imageCurrent);

    statusBar()->showMessage("火焰检测完成！");
}

void JZJ249350520MainWindow::processVideoFrame()
{
    // 空实现，保留以兼容可能的未来扩展
}

void JZJ249350520MainWindow::applyFrameProcessing(int operation)
{
    // 空实现，保留以兼容可能的未来扩展
}

void JZJ249350520MainWindow::openImage()
{
    QString filter = "Image Files (*.png *.jpg *.bmp *.jpeg);;All Files (*.*)";
    QString fileName = QFileDialog::getOpenFileName(this, "打开图片", QDir::homePath(), filter);
    if (!fileName.isEmpty()) {
        if (!imageOriginal.load(fileName)) {
            showMsgBox("打开失败", "无法打开该图片文件。");
            return;
        }
        imageCurrent = imageOriginal;
        brightness = 0;
        contrast = 1.0;
        if (ui->sliderBrightness) ui->sliderBrightness->setValue(0);
        if (ui->sliderContrast) ui->sliderContrast->setValue(10);
        showImage(imageCurrent);
        statusBar()->showMessage("已打开: " + fileName);
    }
}

void JZJ249350520MainWindow::saveImage()
{
    if (!isImageLoaded()) {
        showMsgBox("提示", "没有图片可以保存！");
        return;
    }
    QString filter = "PNG (*.png);;JPG (*.jpg);;BMP (*.bmp)";
    QString fileName = QFileDialog::getSaveFileName(this, "保存图片", QDir::homePath(), filter);
    if (!fileName.isEmpty()) {
        if (imageCurrent.save(fileName)) {
            statusBar()->showMessage("图片已保存到: " + fileName);
        } else {
            showMsgBox("保存失败", "保存图片失败！");
        }
    }
}

void JZJ249350520MainWindow::toGray()
{
    if (!isImageLoaded()) {
        showMsgBox("提示", "请先打开图片！");
        return;
    }
    QImage grayImg = imageCurrent.convertToFormat(QImage::Format_Grayscale8);
    imageCurrent = grayImg;
    showImage(imageCurrent);
    statusBar()->showMessage("已完成灰度化处理");
}

void JZJ249350520MainWindow::toBinary()
{
    if (!isImageLoaded()) {
        showMsgBox("提示", "请先打开图片！");
        return;
    }
    int threshold = sliderThreshold()->value();
    QImage grayImg = imageCurrent.convertToFormat(QImage::Format_Grayscale8);
    QImage binaryImg(grayImg.size(), QImage::Format_Grayscale8);

    for (int y = 0; y < grayImg.height(); ++y) {
        uchar *scan = binaryImg.scanLine(y);
        const uchar *src = grayImg.constScanLine(y);
        for (int x = 0; x < grayImg.width(); ++x) {
            scan[x] = src[x] > threshold ? 255 : 0;
        }
    }
    imageCurrent = binaryImg;
    showImage(imageCurrent);
    statusBar()->showMessage(QString("已完成二值化处理 (阈值:%1)").arg(threshold));
}

void JZJ249350520MainWindow::meanFilter()
{
    if (!isImageLoaded()) {
        showMsgBox("提示", "请先打开图片！");
        return;
    }
    QImage img = imageCurrent.convertToFormat(QImage::Format_ARGB32);
    cv::Mat mat(img.height(), img.width(), CV_8UC4, (void*)img.constBits(), img.bytesPerLine());
    cv::Mat matOut;
    cv::blur(mat, matOut, cv::Size(3, 3));
    QImage result((const uchar*)matOut.data, matOut.cols, matOut.rows, matOut.step, QImage::Format_ARGB32);
    imageCurrent = result.copy();
    showImage(imageCurrent);
    statusBar()->showMessage("已完成3x3均值滤波");
}

void JZJ249350520MainWindow::gammaTransform()
{
    if (!isImageLoaded()) {
        showMsgBox("提示", "请先打开图片！");
        return;
    }
    double gamma = 0.4;
    QImage img = imageCurrent.convertToFormat(QImage::Format_RGB32);
    QImage out(img.size(), img.format());
    for (int y = 0; y < img.height(); ++y) {
        QRgb *line = (QRgb*)img.scanLine(y);
        QRgb *outLine = (QRgb*)out.scanLine(y);
        for (int x = 0; x < img.width(); ++x) {
            int r = qRed(line[x]);
            int g = qGreen(line[x]);
            int b = qBlue(line[x]);
            r = std::pow(r / 255.0, gamma) * 255;
            g = std::pow(g / 255.0, gamma) * 255;
            b = std::pow(b / 255.0, gamma) * 255;
            outLine[x] = qRgb(r, g, b);
        }
    }
    imageCurrent = out;
    showImage(imageCurrent);
    statusBar()->showMessage("已完成伽马变换");
}

void JZJ249350520MainWindow::edgeDetect()
{
    if (!isImageLoaded()) {
        showMsgBox("提示", "请先打开图片！");
        return;
    }
    QImage grayImg = imageCurrent.convertToFormat(QImage::Format_Grayscale8);
    cv::Mat mat(grayImg.height(), grayImg.width(), CV_8UC1, (void*)grayImg.constBits(), grayImg.bytesPerLine());
    cv::Mat edges;
    cv::Canny(mat, edges, 80, 160);
    QImage outImg(edges.data, edges.cols, edges.rows, edges.step, QImage::Format_Grayscale8);
    imageCurrent = outImg.copy();
    showImage(imageCurrent);
    statusBar()->showMessage("已完成边缘检测");
}

void JZJ249350520MainWindow::showAbout()
{
    QString info = "数字图像处理软件V1.0\n金智杰 249350520";
    QMessageBox::about(this, "关于本软件", info);
}

void JZJ249350520MainWindow::onSliderThresholdChanged(int)
{
    // 空，按需实时调用 toBinary
}

void JZJ249350520MainWindow::on_btnRotateLeft_clicked()
{
    if (!isImageLoaded()) return;
    QImage src = imageCurrent.convertToFormat(QImage::Format_RGB888).copy();
    cv::Mat mat(src.height(), src.width(), CV_8UC3, (void*)src.bits(), src.bytesPerLine());
    cv::Mat rotated;
    cv::rotate(mat, rotated, cv::ROTATE_90_CLOCKWISE);
    QImage dst(rotated.data, rotated.cols, rotated.rows, rotated.step, QImage::Format_RGB888);
    imageCurrent = dst.copy();
    showImage(imageCurrent);
}

void JZJ249350520MainWindow::on_btnRotateRight_clicked()
{
    if (!isImageLoaded()) return;
    QImage src = imageCurrent.convertToFormat(QImage::Format_RGB888).copy();
    cv::Mat mat(src.height(), src.width(), CV_8UC3, (void*)src.bits(), src.bytesPerLine());
    cv::Mat sharpened;
    cv::Mat kernel = (cv::Mat_<float>(3,3) <<
                          0, -1,  0,
                      -1,  5, -1,
                      0, -1,  0);
    cv::filter2D(mat, sharpened, mat.depth(), kernel);
    QImage dst(sharpened.data, sharpened.cols, sharpened.rows, sharpened.step, QImage::Format_RGB888);
    imageCurrent = dst.copy();
    showImage(imageCurrent);
}

void JZJ249350520MainWindow::on_btnFlip_clicked()
{
    if (!isImageLoaded()) {
        showMsgBox("提示", "请先打开图片！");
        return;
    }
    int originalWidth = imageCurrent.width();
    int originalHeight = imageCurrent.height();
    int newWidth = originalWidth / 2;
    int newHeight = originalHeight / 2;
    newWidth = qMax(1, newWidth);
    newHeight = qMax(1, newHeight);

    QImage scaledImage = imageCurrent.scaled(
        newWidth,
        newHeight,
        Qt::KeepAspectRatio,
        Qt::SmoothTransformation
        );

    imageCurrent = scaledImage;
    showImage(imageCurrent);
    statusBar()->showMessage(
        QString("图片已缩小: %1×%2 → %3×%4")
            .arg(originalWidth).arg(originalHeight)
            .arg(newWidth).arg(newHeight)
        );
}

void JZJ249350520MainWindow::on_btnReset_clicked()
{
    if (!isImageLoaded()) return;
    imageCurrent = imageOriginal;
    brightness = 0;
    contrast = 1.0;
    if (ui->sliderBrightness) ui->sliderBrightness->setValue(0);
    if (ui->sliderContrast) ui->sliderContrast->setValue(10);
    showImage(imageCurrent);
}

void JZJ249350520MainWindow::on_sliderBrightness_valueChanged(int value)
{
    brightness = value;
    applyBrightnessContrast();
}

void JZJ249350520MainWindow::on_sliderContrast_valueChanged(int value)
{
    contrast = value / 10.0;
    applyBrightnessContrast();
}

void JZJ249350520MainWindow::applyBrightnessContrast()
{
    if (!isImageLoaded()) return;
    QImage src = imageOriginal;
    QImage dst(src.size(), src.format());

    for (int y = 0; y < src.height(); ++y) {
        QRgb *srcLine = (QRgb*)src.constScanLine(y);
        QRgb *dstLine = (QRgb*)dst.scanLine(y);
        for (int x = 0; x < src.width(); ++x) {
            int r = qBound(0, int((qRed(srcLine[x]) * contrast) + brightness), 255);
            int g = qBound(0, int((qGreen(srcLine[x]) * contrast) + brightness), 255);
            int b = qBound(0, int((qBlue(srcLine[x]) * contrast) + brightness), 255);
            dstLine[x] = qRgb(r, g, b);
        }
    }
    imageCurrent = dst;
    showImage(imageCurrent);
}

void JZJ249350520MainWindow::showImage(const QImage &img) {
    if (!imageLabel()) return;

    // 仅用于显示的副本，防止水印反复叠加
    QImage displayImg = img.convertToFormat(QImage::Format_RGB888).copy();

    // 使用 QPainter 添加水印（只加在显示用图像上）
    QPainter painter(&displayImg);
    painter.setPen(QPen(Qt::white));
    painter.setFont(QFont("微软雅黑", 16));
    painter.drawText(10, displayImg.height() - 10, "金智杰249350520");
    painter.end();

    // 缩放并显示
    QPixmap pixmap = QPixmap::fromImage(displayImg).scaled(imageLabel()->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
    imageLabel()->setPixmap(pixmap);
}


bool JZJ249350520MainWindow::isImageLoaded() const
{
    return !imageCurrent.isNull();
}

void JZJ249350520MainWindow::showMsgBox(const QString &title, const QString &info)
{
    QMessageBox::information(this, title, info);
}

QLabel* JZJ249350520MainWindow::imageLabel()
{
    return findChild<QLabel*>("imageLabel");
}

QSlider* JZJ249350520MainWindow::sliderThreshold()
{
    return findChild<QSlider*>("sliderThreshold");
}

void JZJ249350520MainWindow::openVideo()
{
    QString fileName = QFileDialog::getOpenFileName(this,
                                                    "打开视频文件",
                                                    QDir::homePath(),
                                                    "视频文件 (*.mp4 *.avi *.mov *.mkv)");

    if (!fileName.isEmpty()) {
        mediaPlayer->setSource(QUrl::fromLocalFile(fileName));
        if (mediaPlayer->error() != QMediaPlayer::NoError) {
            QMessageBox::warning(this, "错误", "无法加载视频文件: " + mediaPlayer->errorString());
            return;
        }

        // 等待元数据可用以获取视频分辨率
        connect(mediaPlayer, &QMediaPlayer::mediaStatusChanged, this, [this](QMediaPlayer::MediaStatus status) {
            if (status == QMediaPlayer::LoadedMedia) {
                QSize resolution = mediaPlayer->metaData().value(QMediaMetaData::Resolution).toSize();
                if (!resolution.isEmpty()) {
                    videoWidget->setMinimumSize(resolution);
                    videoWidget->setMaximumSize(resolution);
                    qDebug() << "视频分辨率:" << resolution;
                } else {
                    qWarning() << "无法获取视频分辨率";
                }
            }
        });

        mediaPlayer->play();
        videoWidget->show();
        statusBar()->showMessage("正在播放: " + fileName);
    }
}

void JZJ249350520MainWindow::closeEvent(QCloseEvent *event)
{
    int ret = QMessageBox::question(this, "退出确认", "确定要退出吗？", QMessageBox::Yes | QMessageBox::No);
    if (ret == QMessageBox::Yes) {
        event->accept();
    } else {
        event->ignore();
    }
}
